package main

import (
	"context"
	"fmt"
	"go_rpc/grpc_test/proto"
	"google.golang.org/grpc"
)

type customCredential struct {
}

func (c *customCredential) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
	return map[string]string{
		"appid":  "101010",
		"appkey": "I am key",
	}, nil
}
func (c *customCredential) RequireTransportSecurity() bool {
	return false
}
func main() {
	// 客户端拦截器与服务端拦截器有所不同
	// go-grpc-middleware
	/*
			grpc-auth:认证
			grpc-zap 调用日志打印(grpc-logrus|grpc-kit)
		Monitor:
			grpc_opentracing -OpenTracing client-side and server-side interceptors with support fostreaming and handler-.returned tag
			grpc-prometheus:监控
		Client
			grpc-retry 	重试
		Server
			grpc-recovery:异常恢复(turn panics into gRPC errors)
		    grpc-validator: 参数校验(从原型选项编码入站消息验证)
			ratelimit :限流（grpc 速率 通过自己的限制规则）

	*/
	//interceptor := func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
	//	start := time.Now()
	//	md := metadata.New(map[string]string{
	//		"appid":  "1010120",
	//		"appkey": "I am key",
	//	})
	//	ctx = metadata.NewOutgoingContext(context.Background(), md)
	//	err := invoker(ctx, method, req, reply, cc, opts...)
	//	fmt.Printf("耗时: %s\n", time.Since(start))
	//	return err
	//}
	//opt := grpc.WithUnaryInterceptor(interceptor)

	var opts []grpc.DialOption
	opts = append(opts, grpc.WithInsecure())
	opts = append(opts, grpc.WithPerRPCCredentials(&customCredential{}))
	//conn, err := grpc.Dial("127.0.0.1:8080", opts...)
	conn, err := grpc.NewClient("127.0.0.1:8080", opts...)
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	client := proto.NewGreeterClient(conn)
	reply, err := client.SayHello(context.Background(), &proto.HelloRequest{Name: "我是client端"})

	if err != nil {
		fmt.Println("异常:", err.Error())
		panic(err)
	}

	fmt.Println(reply.Message)

	// stream:流模式 比如在直播场景
}

/**
	简单模式 simple rpc
		客户端发起一次请求，服务端响应一个数据
服务端数据流模式 server-side streaming rpc
		客户端发起，服务端返回一个连续的数据流。典型的例子就是客户端向服务端发送一个股票代码，服务端就把这个股票的实时数据源源不断地返回客户端。
	客户端数据流模式 client-side streaming rpc
		服务端发起，客户端向服务端发送数据流，而发送结束后，由服务端返回一个响应。典型的例子就是物联网终端向服务器报送数据。
	双向数据流模式 bidirectional streaming rpc
		客户端和服务端都可以给对方发送数据流，这个时候双方的数据可以同时互相发送，也就是可以实现实时交互。典型的例子是聊天机器人。
*/
